package cemp.util;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局异常处理器，将 Exception 翻译成 Response + 对应的异常编号
 *
 * @author 张力方
 */
@RestControllerAdvice
@AllArgsConstructor
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 处理自定义异常
     */
    @ExceptionHandler(RuntimeException.class)//处理特定异常
    public String handleBizException(RuntimeException ex){
        log.error("发生异常",ex);
        return ex.getMessage();
    }

//    /**
//     * 处理所有异常，主要是提供给 Filter 使用
//     * 因为 Filter 不走 SpringMVC 的流程，但是我们又需要兜底处理异常，所以这里提供一个全量的异常处理过程，保持逻辑统一。
//     *
//     * @param request 请求
//     * @param ex      异常
//     * @return 通用返回
//     */
//    public Response<?> allExceptionHandler(HttpServletRequest request, Throwable ex) {
//        if (ex instanceof MissingServletRequestParameterException) {
//            return missingServletRequestParameterExceptionHandler(request, (MissingServletRequestParameterException) ex);
//        }
//        if (ex instanceof MethodArgumentTypeMismatchException) {
//            return methodArgumentTypeMismatchExceptionHandler(request, (MethodArgumentTypeMismatchException) ex);
//        }
//        if (ex instanceof MethodArgumentNotValidException) {
//            return methodArgumentNotValidExceptionExceptionHandler((MethodArgumentNotValidException) ex);
//        }
//        if (ex instanceof BindException) {
//            return bindExceptionHandler((BindException) ex);
//        }
//        if (ex instanceof ConstraintViolationException) {
//            return constraintViolationExceptionHandler((ConstraintViolationException) ex);
//        }
//        if (ex instanceof NoHandlerFoundException) {
//            return noHandlerFoundExceptionHandler((NoHandlerFoundException) ex);
//        }
//        if (ex instanceof HttpRequestMethodNotSupportedException) {
//            return httpRequestMethodNotSupportedExceptionHandler((HttpRequestMethodNotSupportedException) ex);
//        }
//        if (ex instanceof ServiceException) {
//            return serviceExceptionHandler((ServiceException) ex);
//        }
//        return defaultExceptionHandler(request, ex);
//    }
//
//    /**
//     * 处理 SpringMVC 请求参数缺失
//     * <p>
//     * 例如说，接口上设置了 @RequestParam("xx") 参数，结果并未传递 xx 参数
//     */
//    @ExceptionHandler(value = MissingServletRequestParameterException.class)
//    public Response<?> missingServletRequestParameterExceptionHandler(HttpServletRequest request, MissingServletRequestParameterException ex) {
//        log.warn("接口" + request.getRequestURL().toString() + "缺少参数：" + ex.getParameterName());
//        log.warn("[missingServletRequestParameterExceptionHandler]", ex);
//        return Response.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), String.format("请求参数缺失:%s", ex.getParameterName()));
//    }
//
//    /**
//     * 处理 SpringMVC 请求参数类型错误
//     * <p>
//     * 例如说，接口上设置了 @RequestParam("xx") 参数为 Integer，结果传递 xx 参数类型为 String
//     */
//    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
//    public Response<?> methodArgumentTypeMismatchExceptionHandler(HttpServletRequest request, MethodArgumentTypeMismatchException ex) {
//        log.warn("接口" + request.getRequestURL().toString() + "参数类型错误：" + ex.getParameter().getParameterName());
//        log.warn("[missingServletRequestParameterExceptionHandler]", ex);
//        return Response.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), String.format("请求参数类型错误:%s", ex.getMessage()));
//    }
//
//    /**
//     * 处理 SpringMVC 参数校验不正确
//     */
//    @ExceptionHandler(MethodArgumentNotValidException.class)
//    public Response<?> methodArgumentNotValidExceptionExceptionHandler(MethodArgumentNotValidException ex) {
//        log.warn("[methodArgumentNotValidExceptionExceptionHandler]", ex);
//        FieldError fieldError = ex.getBindingResult().getFieldError();
//        assert fieldError != null; // 断言，避免告警
//        return Response.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), String.format("请求参数不正确:%s", fieldError.getDefaultMessage()));
//    }
//
//    /**
//     * 处理 SpringMVC 参数绑定不正确，本质上也是通过 Validator 校验
//     */
//    @ExceptionHandler(BindException.class)
//    public Response<?> bindExceptionHandler(BindException ex) {
//        log.warn("[handleBindException]", ex);
//        FieldError fieldError = ex.getFieldError();
//        assert fieldError != null; // 断言，避免告警
//        return Response.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), String.format("请求参数不正确:%s", fieldError.getDefaultMessage()));
//    }
//
//    /**
//     * 处理 Validator 校验不通过产生的异常
//     */
//    @ExceptionHandler(value = ConstraintViolationException.class)
//    public Response<?> constraintViolationExceptionHandler(ConstraintViolationException ex) {
//        log.warn("[constraintViolationExceptionHandler]", ex);
//        ConstraintViolation<?> constraintViolation = ex.getConstraintViolations().iterator().next();
//        return Response.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), String.format("请求参数不正确:%s", constraintViolation.getMessage()));
//    }
//
//    /**
//     * 处理 SpringMVC 请求地址不存在
//     * <p>
//     * 注意，它需要设置如下两个配置项：
//     * 1. spring.mvc.throw-exception-if-no-handler-found 为 true
//     * 2. spring.mvc.static-path-pattern 为 /statics/**
//     */
//    @ExceptionHandler(NoHandlerFoundException.class)
//    public Response<?> noHandlerFoundExceptionHandler(NoHandlerFoundException ex) {
//        log.warn("[noHandlerFoundExceptionHandler]", ex);
//        return Response.error(GlobalErrorCodeConstants.NOT_FOUND.getCode(), String.format("请求地址不存在:%s", ex.getRequestURL()));
//    }
//
//    /**
//     * 处理 SpringMVC 请求方法不正确
//     * <p>
//     * 例如说，A 接口的方法为 GET 方式，结果请求方法为 POST 方式，导致不匹配
//     */
//    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
//    public Response<?> httpRequestMethodNotSupportedExceptionHandler(HttpRequestMethodNotSupportedException ex) {
//        log.warn("[httpRequestMethodNotSupportedExceptionHandler]", ex);
//        return Response.error(GlobalErrorCodeConstants.METHOD_NOT_ALLOWED.getCode(), String.format("请求方法不正确:%s", ex.getMessage()));
//    }
//
//    /**
//     * 处理业务异常 ServiceException
//     * <p>
//     * 例如说，商品库存不足，用户手机号已存在。
//     */
//    @ExceptionHandler(value = ServiceException.class)
//    public Response<?> serviceExceptionHandler(ServiceException ex) {
//        log.info("[serviceExceptionHandler]", ex);
//        return Response.error(ex.getCode(), ex.getMessage());
//    }
//
//    /**
//     * 处理非法参数异常
//     */
//    @ExceptionHandler(value = IllegalArgumentException.class)
//    public Response<?> defaultExceptionHandler(IllegalArgumentException exception) {
//        log.error("[illegalArgumentException]", exception);
//        // 返回 ERROR Response
//        return Response.error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), exception.getMessage());
//    }
//
//    /**
//     * 处理系统异常，兜底处理所有的一切
//     */
//    @ExceptionHandler(value = Exception.class)
//    public Response<?> defaultExceptionHandler(HttpServletRequest req, Throwable ex) {
//        log.error("[defaultExceptionHandler]", ex);
//        // 返回 ERROR Response
//        return Response.error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getMsg());
//    }
//
//    /**
//     * 处理系统异常，兜底处理所有的一切
//     */
//    @ExceptionHandler(value = BusinessException.class)
//    public Response<?> businessExceptionHandler(HttpServletRequest req, BusinessException ex) {
//        log.error("[businessExceptionHandler]", ex);
//        // 返回 ERROR Response
//        return Response.error(ex.getErrorCode(), ex.getMessage());
//    }
}
